﻿using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using MX.Core.Assets;
using MX.Core.Http.MVC.Model;
using MX.Core.Log;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;

using VC.Admin.Core;
using VC.Admin.Models;
using VC.BLL;
using VC.Models;
using Xabe.FFmpeg;
using Xabe.FFmpeg.Enums;
using Xabe.FFmpeg.Model;
using Xabe.FFmpeg.Streams;

namespace VC.Admin.Controllers
{
    [Route("api/video/[action]")]
    public class VideoController : BaseController
    {
        [ActionName("add")]
        public IActionResult Add(string coverUrl, int duration, int height, int size, string title, string videoUrl, int width)
        {
            var result = new MXResult();
            var added = VideoBLL.Insert(new Video()
            {
                Attr = 0,
                Audit = true,
                CoverUrl = coverUrl,
                Duration = duration,
                Enable = true,
                Height = height,
                HotValue = 0,
                MemberId = MemberId,
                Size = size,
                VideoUrl = videoUrl,
                Width = width,
                Title = title
            });
            if (!added)
            {
                result.SetError(6010, "数据写入失败，请重试");
            }
            return Json(result);
        }

        [HttpPost(), ActionName("upload"), DisableRequestSizeLimit]
        public async Task<IActionResult> Upload()
        {
            var result = new MXResult();

            var files = Request.Form.Files;
            if (files.Count < 1)
            {
                result.SetError(6007, "请上传文件");
            }
            else
            {
                var file = files[0];
                var fileName = file.FileName;
                var fileExtension = Path.GetExtension(fileName);
                if (!string.IsNullOrEmpty(fileExtension))
                    fileExtension = fileExtension.ToLowerInvariant();
                string[] allowFiles = new string[3] { ".flv", ".mp4", ".avi" };
                if (!allowFiles.Contains(fileExtension))
                {
                    result.SetError(6002, $"文件类型为{string.Join(",", allowFiles)}");
                }
                else
                {
                    var tempVideoFilePath = Path.Combine("video", Guid.NewGuid().ToString("N") + fileName);
                    using (var fileStream = new FileStream(tempVideoFilePath, FileMode.Create))
                    {
                        await file.CopyToAsync(fileStream);
                    }
                    var coverFilePath = Path.Combine(Path.GetDirectoryName(tempVideoFilePath), $"{ Path.GetFileNameWithoutExtension(fileName)}.webp");
                    var videoFilePath = Path.Combine(Path.GetDirectoryName(tempVideoFilePath), $"{ Path.GetFileNameWithoutExtension(fileName)}.mp4");
                    if (!string.IsNullOrEmpty(AppConfig.Default.FFmpegExecutablePath))
                    {
                        FFmpeg.ExecutablesPath = AppConfig.Default.FFmpegExecutablePath;
                    }
                    IMediaInfo mediaInfo = null;
                    IVideoStream videoStream = null;
                    for (int i = 0; i < 2; i++)
                    {
                        try
                        {
                            mediaInfo = await MediaInfo.Get(tempVideoFilePath);
                            videoStream = mediaInfo.VideoStreams.FirstOrDefault();
                            if (mediaInfo.AudioStreams.Any())
                            {
                                IStream audioStream = mediaInfo.AudioStreams.FirstOrDefault().SetCodec(AudioCodec.Aac);
                                IConversionResult convertResult = await Conversion.New().AddStream(audioStream, videoStream.SetCodec(new VideoCodec(AppConfig.Default.FFmpegCodec))).
                                    SetOutput(videoFilePath).SetOverwriteOutput(true).AddParameter(AppConfig.Default.FFmpegParameter, ParameterPosition.PostInput).Start();
                                if (!convertResult.Success)
                                {
                                    throw new Exception("视频文件转换H265错误");
                                }
                                convertResult = await new Conversion().AddStream(videoStream.SetCodec(new VideoCodec("webp")).SetOutputFramesCount(1)).SetOutput(coverFilePath).SetOverwriteOutput(true).Start();
                                if (!convertResult.Success)
                                {
                                    throw new Exception("视频文件获取截图错误");
                                }
                                break;
                            }
                            else
                            {
                                throw new Exception("视频不包含音频流");
                            }

                        }
                        catch (Exception ex)
                        {
                            mediaInfo = null;
                            videoStream = null;
                            Logger.Default.Error(ex, "");
                            await Task.Delay(200);
                        }
                    }
                    if (mediaInfo == null || videoStream == null)
                    {
                        result.SetError(6004, "视频文件解析失败");
                    }
                    else
                    {
                        int width = videoStream.Width;
                        int height = videoStream.Height;
                        int duration = Convert.ToInt32(mediaInfo.Duration.TotalSeconds);
                        long size = mediaInfo.Size;
                        var videoUploadResult = FileUploader.Upload(AppConfig.Default.ResHost, videoFilePath);
                        if (videoUploadResult.code != ReponseCode.SUCCESSED)
                        {

                            result.SetError(6005, "视频文件上传失败");
                        }
                        else
                        {
                            var coverUploadResult = FileUploader.Upload(AppConfig.Default.ResHost, coverFilePath);
                            if (coverUploadResult.code != ReponseCode.SUCCESSED)
                            {
                                result.SetError(6006, "封面文件上传失败");
                            }
                            else
                            {
                                result.Data = new { coverUrl = coverUploadResult.url, videoUrl = videoUploadResult.url, width = width, height = height, duration = duration, size = size };
                            }
                        }
                    }
                    System.IO.File.Delete(tempVideoFilePath);
                    System.IO.File.Delete(coverFilePath);
                    System.IO.File.Delete(videoFilePath);
                }

            }
            return Json(result);

        }


        [HttpGet, ActionName("list")]
        public IActionResult List(string keywords = "", int pageIndex = 1, int pageSize = 10)
        {
            var result = new MXResult();
            var pageResult = VideoBLL.List(keywords, pageSize, pageIndex);
            result.Data = pageResult;
            return Json(result);
        }

        [HttpGet, ActionName("del")]
        public IActionResult Disable(long videoId)
        {
            var result = new MXResult();
            var updated = VideoBLL.SetStatus(videoId, false);
            if (!updated)
            {
                result.SetError(6011, "数据写入失败，请重试");
            }
            return Json(result);
        }
    }
}